/**   
 * @Title: FileUtil.java
 * @Package cn.edu.sjtu.se.dslab.util
 * @Description: define the FileUtil class
 * @author longshaohang
 * @date 2013-7-21 上午9:25:50
 * @version V1.0
 */ 
package cn.edu.sjtu.se.dslab.util;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.springframework.web.multipart.MultipartFile;

/** 
 * @ClassName: FileUtil
 * @Description: tool class for copy file or directory 
 * @author longshaohang
 * @date 2013-7-21 上午9:25:50
 * 
 */
public class FileUtil {
	
	private static Logger logger = Logger.getLogger(FileUtil.class);
	
	/**
	 * 
	* @Title: copyFile
	* @Description: 把sourceFilePath的文件复制到targetDirPath的目录下
	* @param sourceFilePath
	* @param targetDirPath
	* @throws IOException
	* @return boolean
	 */
	public static boolean copyFile(String sourceFilePath, String targetDirPath, String newFileName) throws IOException{
		boolean isSuccess = false;
		File srcFile = new File(sourceFilePath);
		if (!srcFile.exists()){
			logger.info("The source file :" + sourceFilePath + " is not exist!");
			return false;
		}
		File tagDir = new File(targetDirPath);
		if (!tagDir.exists()){
			logger.info("create target directorys :" + targetDirPath);
			tagDir.mkdirs();
		}
		StringBuffer tagFilePath = new StringBuffer(targetDirPath);
		if (newFileName==null || newFileName.equals("")){
			String fileName = sourceFilePath.substring(
					sourceFilePath.lastIndexOf('/') + 1, sourceFilePath.length());
			tagFilePath.append("/").append(fileName);
		}else{
			tagFilePath.append("/").append(newFileName);
		}
		File tagFile = new File( tagFilePath.toString() );
		//BufferedInputStream bis = null;
		//BufferedOutputStream bos = null;
		
		BufferedReader inputReader = null;
		BufferedWriter outWriter = null;
		
		try {
			if (tagFile.exists()){
				logger.info("target file:" + tagFilePath.toString() + " has exist!");
				logger.info("Overwrite it!");
			}else{
				tagFile.createNewFile();
			}
			//bis = new BufferedInputStream( new FileInputStream(srcFile));
			//以utf-8编码从文件中读取字符
			inputReader = new BufferedReader(new InputStreamReader(new FileInputStream(srcFile),"UTF-8"));
			//bos = new BufferedOutputStream( new FileOutputStream(tagFile));
			//以gbk编码写入字符
			outWriter = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(tagFile), "GBK"));  
			int size;
			while( (size = inputReader.read()) != -1){
				outWriter.write(size);
			}
			isSuccess = true;
		}// catch (FileNotFoundException e) {
		//	e.printStackTrace();
		//} catch (IOException e) {
		//	e.printStackTrace();
		//}
		finally{
			try {
				if (inputReader != null){
					inputReader.close();
				}
				if (outWriter != null){
					outWriter.flush();
					outWriter.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
		return isSuccess;
	}
	
	/**
	 * 
	 * @param sourceFilePath
	 * @param targetDirPath
	 * @return
	 * @throws IOException
	 */
	public static boolean copyFileList(Set<String> sourceFileList, String targetDirPath) throws IOException{
		for (String filePath: sourceFileList){
			copyFile(filePath, targetDirPath, null);
			logger.info(filePath + "============>>>>>>>>");
			logger.info(targetDirPath);
		}
		return true;
	}
	
	/**
	 * 
	* @Title: copyDir
	* @Description: 把sourceDirPath目录复制到targetDirPath目录下
	* @param sourceDirPath
	* @param targetDirPath
	* @throws IOException
	* @return boolean
	 */
	public static boolean copyDir(String sourceDirPath, String targetDirPath, String newDirName) throws IOException{
		logger.info("separate" + File.separator);
		logger.info("copy dir:" + sourceDirPath);
		boolean isSuccess = false;
		File sourceDir = new File(sourceDirPath);
		if (!sourceDir.exists()){
			logger.error("Source directory " + sourceDirPath + " is not exist!");
			return false;
		}
		if (!sourceDir.isDirectory()){
			logger.error(sourceDirPath + " is not a directory!");
			return false;
		}
		StringBuffer srcDirPath = new StringBuffer(sourceDirPath);
		//make it the right source directory path
		if ( sourceDirPath.charAt(sourceDirPath.length() -1 ) != '/'){
			srcDirPath.append('/');
			System.out.println("src:" + srcDirPath.toString());
		}
		StringBuffer tagDirPath = new StringBuffer(targetDirPath);
		//make it the right target directory path
		if ( targetDirPath.charAt(targetDirPath.length() -1 ) != '/'){
			tagDirPath.append('/');
			System.out.println("tag:" + tagDirPath.toString());
		}
		
		File[] sourceFiles = sourceDir.listFiles();
		for (File srcFile : sourceFiles){
			//construct the current source file's path
			StringBuffer currentFilePath = new StringBuffer(srcDirPath.toString());
			currentFilePath.append(srcFile.getName());
			//construct the target directory path for the current source file
			StringBuffer currentTagDirPath = new StringBuffer(tagDirPath.toString());
			if (null != newDirName && "" != newDirName){
				currentTagDirPath.append(newDirName.trim()).append("/");
			}else{
				currentTagDirPath.append(sourceDir.getName()).append("/");
			}
			System.out.println("current source file:" + currentFilePath.toString());
			if (srcFile.isFile()){
				isSuccess = copyFile(currentFilePath.toString(), currentTagDirPath.toString(), null);
			}else if( srcFile.isDirectory()){
				isSuccess = copyDir(currentFilePath.append("/").toString(), currentTagDirPath.toString(), null);
			}
			if (!isSuccess) return false;
		}
		return true;
		
	}
	
	public static boolean createDirectory(String targetDirName){
		File dir = new File(targetDirName);
		if (!dir.exists()){
			 return dir.mkdir();
		}
		return true;

	}
	
	/**
	 * 
	* @Title: createDirectorys
	* @Description: create the directory, including the parent
	* @param targetDirPath the relative path of the directory
	* @return boolean successfully create or not
	 */
	public static boolean createDirectorys(String targetDirPath){
		String rootPath = getRootPath();
		if (targetDirPath.startsWith("/")){
			targetDirPath = rootPath.substring(0, rootPath.length()-2) + targetDirPath;
		}else{
			targetDirPath = rootPath + targetDirPath;
		}
		File dir = new File( targetDirPath);
		if (!dir.exists()){
			 return dir.mkdirs();
		}
		return true;
	}
	
	/**
	 * 
	* @Title: getRootPath
	* @Description: return the root path of the project
	* @return String the absolute path of the web project,if not exist ,return null
	 */
	public static String getRootPath(){
		URL rootPath =  FileUtil.class.getResource("/");
		if (rootPath != null){
			return rootPath.getPath();
		}
		return null;
	}
	
	/**
	 * 
	 * @param sourceFile
	 * @param targetDir 绝对路径
	 * @return
	 * @throws IOException
	 */
	public static String uploadFile(MultipartFile sourceFile, String targetDir) throws IOException{
		String originalName = sourceFile.getOriginalFilename();
		String postFix = originalName.substring(originalName.lastIndexOf('.'), originalName.length());
		String fileName = DateUtil.getDateAsFileNameString(DateUtil.COMMON_DATE_PATTERN) + postFix;
		FileUtils.copyInputStreamToFile(sourceFile.getInputStream(), new File( targetDir, fileName));
		return fileName;
	}
	
	/**
	 * input the target relative file path, return the corresponding file
	 * if the file not exist , just create a new one
	 * @param targetFilePath
	 * @return
	 */
	public static File getOldOrCreateFile(String targetFilePath){
		File targetFile = new File(getRootPath() + targetFilePath);
		if (!targetFile.exists()){
			System.out.println("FileUtil: create new file:" + targetFile.getAbsolutePath());
			try {
				targetFile.createNewFile();
			} catch (IOException e){
				e.printStackTrace();
			}
		}else{
			System.out.println("FileUtil: return old File:" + targetFile.getName());
		}
		return targetFile;
	}
	
	
	/**
	 * Given a directory, return all the file absolute path in the directory
	 * @param dirPath
	 * @return 
	 */
	public static List<String> getFileAbsolutePathList(String dirPath){
		List<String> filePathList = new ArrayList<String>();
		File dir = new File(dirPath);
		if(!dir.isDirectory() || !dir.exists()){
			return filePathList;
		}
		
		for(File f : dir.listFiles()){
			if(f.isDirectory()){
				filePathList.addAll(getFileAbsolutePathList(f.getAbsolutePath()));
			}else {
				logger.info("Add file to List");
				filePathList.add(f.getAbsolutePath());
			}
		}
		return filePathList;
	}
}















